// MyListCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "gp_uv_rc.h"
//#include "ListviewControlEditable.h"
#include "ListCtrlEdit.h"
/*
#include "MyEdit.h"
#include "MyCombo.h"
*/
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEdit

/*
extern CEdit *m_pEdit ;
extern CComboBox *m_pcombo ;
extern int m_iRow;
extern int m_iCol;
*/

CListCtrlEdit::CListCtrlEdit()
{
	m_pEdit = NULL;
//	m_pcombo = NULL;
	m_iRow = 0;
	m_iCol = -1;
	m_bEditable = false;
}

CListCtrlEdit::~CListCtrlEdit()
{
//	if(m_pcombo) delete m_pcombo;
	if(m_pEdit) delete m_pEdit;
//	if(m_pSpin) delete m_pSpin;
}


BEGIN_MESSAGE_MAP(CListCtrlEdit, CListCtrl)
	//{{AFX_MSG_MAP(CListCtrlEdit)
	ON_WM_VSCROLL()
	ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick)
	ON_NOTIFY_REFLECT_EX(NM_CLICK, OnClick)
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CListCtrlEdit message handlers

void CListCtrlEdit::vResetTopPosition()
{
	
	CWnd *wnd = NULL;

/*
	if(m_pcombo)
		wnd = (CWnd*)m_pcombo;
	else 
*/
	if(m_pEdit)
			wnd = (CWnd*)m_pEdit;
	if(wnd)
	{
		CRect rcThis;
		GetWindowRect(rcThis);
		CRect rect;
		if(!GetSubItemRect(m_iRow,m_iCol,LVIR_LABEL,rect)) return;
		ClientToScreen(rect);
		CPoint pt(rect.left,rect.top);
		if(!rcThis.PtInRect(pt))
		{
			//AfxMessageBox("Top");
			SendMessage(WM_VSCROLL,SB_LINEUP,0);			
		}
	}

}
void CListCtrlEdit::vResetBottomPosition()
{
	CWnd *wnd = NULL;

/*
	if(m_pcombo)
		wnd = (CWnd*)m_pcombo;
	else 
*/
	if(m_pEdit)
			wnd = (CWnd*)m_pEdit;
	if(wnd)
	{
		CRect rcThis;
		GetWindowRect(rcThis);
		CRect rect;
		if(!GetSubItemRect(m_iRow,m_iCol,LVIR_LABEL,rect)) return;
		ClientToScreen(rect);
		CPoint pt(rect.right,rect.bottom);
		if(!rcThis.PtInRect(pt))
		{
			//AfxMessageBox("Bottom");
			SendMessage(WM_VSCROLL,SB_LINEDOWN,0);
		}
	}
	
}
void CListCtrlEdit::VerifyScrollPos()
{
	int nTopRowVal = GetTopIndex();
	int nBottomVal = nTopRowVal + m_MaxRowsPerView;//MAX_ROWS_PER_VIEW;
	if(m_iRow>nTopRowVal-1 && m_iRow<nBottomVal+1);
	else
	{
		////////////////Method 1/////////////
		//m_iRow = GetTopIndex(); // Move the control at the top of the visible m_iRow
		////////////////Method 1/////////////
		//SetScrollPos(SB_VERT,0); //Will not work for unknown reasons
		////////////////Method 2/////////////
		////////////////Send the scroll bar top/////////////
		//SendMessage(WM_VSCROLL,SB_TOP,0);
		////////////////Send the scroll bar top/////////////
		////////////////Then bring the scroll bar to the correct position/////////////
		//for( int j=0;j<m_iRow;j++)
		//	SendMessage(WM_VSCROLL,SB_LINEDOWN,0);
		////////////////Then bring the scroll bar to the correct position/////////////
		////////////////Method 2/////////////
		////////////////Method 3/////////////
		////////////////If the m_iRow is above the topmost visisble m_iRow/////////////
		if(m_iRow<nTopRowVal){
			//AfxMessageBox("UP");
			for(int j=0;j<-m_iRow+nTopRowVal;j++)
				SendMessage(WM_VSCROLL,SB_LINEUP,0);
		}
		////////////////If the m_iRow is above the topmost visisble m_iRow/////////////
		////////////////If the m_iRow is below the BottomMost visisble m_iRow/////////////
		if(m_iRow>nBottomVal)
		{
			//AfxMessageBox("DOWN");
			for(int j=0;j<m_iRow-nTopRowVal;j++)
				SendMessage(WM_VSCROLL,SB_LINEDOWN,0);
		}
		////////////////Method 3/////////////
	}
}
BOOL CListCtrlEdit::PreTranslateMessage(MSG* pMsg) 
{
	/*
	if(pMsg->message == WM_LBUTTONUP)
	{
		TCHAR buf[123]={0x00};
		int nTopRowVal = GetTopIndex();
		int nBottomVal = nTopRowVal + MAX_ROWS_PER_VIEW;
		if(m_iRow>nTopRowVal-1 && m_iRow<nBottomVal+1);
		else
			m_iRow = GetTopIndex()+1;
		sprintf_s(buf,"%d",GetTopIndex()+1);
		GetParent()->SetWindowText(buf);
	}
	*/
	if( m_bEditable && pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB )
	{
		//TCHAR buf[123] = {0x00};
		//sprintf_s(buf,"%d",GetKeyState (VK_SHIFT)>>8);
		//AfxMessageBox(buf);
		
		/*
		CRect rc;
		GetSubItemRect(m_iRow-1,m_iCol,LVIR_ICON ,rc);
		//sprintf_s(buf,"m_iRow =%d,m_iCol=%d",info.iItem,m_iCol);
		//sprintf_s(buf,"left =%d,top=%d",rc.left,rc.top);
		//AfxMessageBox(buf);
		if(m_iCol == 0 && rc.top < 10) //return 0; //if you have readhed the top left most cell return form there
		{
			SendMessage(WM_VSCROLL,SB_LINEUP,0);
		}
		*/
		
		OnSetText();

		int iMaxCols = m_vEditable.size() - 1;

		if(GetKeyState(VK_SHIFT)>>8 == -1) //go backwards user is pressing SHIFT + TAB
		{
			m_iCol--;
			if(m_iCol < 0)
			{
				m_iCol = iMaxCols;
				m_iRow--;
				//CPoint pt;
				//GetCursorPos(&pt);
				//mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
				//mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);	
				//SetCursorPos(pt.x,pt.y);
				//SendMessage(WM_VSCROLL,SB_LINEUP,0); // do not do PostMessage
				//vResetTopPosition();
				if(m_iRow < 0)
				{
					m_iCol=0;
					m_iRow=0;
					//return 1;
				}
			}
			//vResetTopPosition();
		}
		else //go forward, user is pressing TAB
		{
			m_iCol++;
			if(m_iCol > iMaxCols )
			{
				m_iCol = 0;
				m_iRow++;
				//SendMessage(WM_VSCROLL,SB_LINEDOWN,0); // do not do PostMessage
				vResetBottomPosition();
				if(m_iRow > MAX_ROWS-1)
				{
					//AfxMessageBox("End of table");
					m_iCol = iMaxCols;
					m_iRow = MAX_ROWS-1;
					//CPoint pt;
					//GetCursorPos(&pt);
					//mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
					//mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);	
					//SetCursorPos(pt.x,pt.y);
					//m_iRow--;
					//return 1;
				}
	
			}
			//vResetBottomPosition();	
		}
		VerifyScrollPos();
		vResetTopPosition();
		vResetBottomPosition();

		switch ( m_vEditable[ m_iCol ] )
		{
			case elcEditable:
				OnEdit();
				break;
		}
		
		//TCHAR buf[1234]={0x00};
		//sprintf_s(buf,"%d",GetTopIndex( ));
		//sprintf_s(buf,"%d",GetCountPerPage());
		//AfxMessageBox(buf);
		return 1;
	}
	
	return CListCtrl::PreTranslateMessage(pMsg);
}

void CListCtrlEdit::OnSetText()
{
	CString strText;

	switch ( m_vEditable[ m_iCol ] )
	{
		case elcEditable:
			m_pEdit->GetWindowText(strText);
			break;
	}

	//AfxMessageBox(sztext);
	strText.TrimLeft();
	strText.TrimRight();
	if(strText.IsEmpty()) return;
	SetItemText(m_iRow,m_iCol,strText);
	
}


LRESULT CListCtrlEdit::OnEdit()
{
	CRect rect;
	GetSubItemRect(m_iRow,m_iCol,LVIR_LABEL,rect);
	CString strItemText = GetItemText( m_iRow, m_iCol );

	if ( !m_pEdit ) m_pEdit = new CNumEdit;
	
	if ( !IsWindow( m_pEdit->m_hWnd ) ) // If Edit box does not exist create one
	{

		DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_TABSTOP | WS_BORDER | ES_LEFT | ES_AUTOHSCROLL; 
		m_pEdit->Create(dwStyle,rect,this,1801);

		m_pEdit->ShowWindow(SW_SHOW);

/*
		dwStyle = 
//			WS_CHILD |
			WS_VISIBLE |
			UDS_ALIGNRIGHT |
			UDS_ARROWKEYS |
//			UDS_AUTOBUDDY |
			0;

		m_pSpin->Create( dwStyle, rect, this, 1802 );
		m_pSpin->ShowWindow(SW_SHOW);
		m_pSpin->SetBuddy( m_pEdit );
		m_pSpin->SetRange( m_SpinSettings.fLower, m_SpinSettings.fUpper );
		m_pSpin->SetPos( m_SpinSettings.fPos );
		m_pSpin->SetDelta( m_SpinSettings.fDelta );
*/


		m_pEdit->SetWindowText( strItemText );
		m_pEdit->SetSel(0,-1);
		m_pEdit->SetFocus();
//		if(m_pcombo) m_pcombo->ShowWindow(SW_HIDE);
	}
	else  //If Edit box exist just move it
	{
		//m_pEdit->SetWindowPos(NULL,rect.left,rect.top,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);
		m_pEdit->SetWindowPos(NULL,rect.left,rect.top,rect.Width(),rect.Height(),SWP_SHOWWINDOW | SWP_FRAMECHANGED);
//		m_pSpin->SetBuddy( m_pEdit );
//		m_pSpin->SetWindowPos( NULL,rect.left,rect.top,rect.Width(),rect.Height(),SWP_NOSIZE|SWP_SHOWWINDOW);
		//m_pEdit->MoveWindow(rect.left,rect.top,rect.Width(),rect.Height(),1);
		m_pEdit->SetWindowText( strItemText );
		m_pEdit->SetSel(0,-1);
		m_pEdit->SetFocus();
//		if(m_pcombo) m_pcombo->ShowWindow(SW_HIDE);
	}
	
	return 21;
}

/*
LRESULT CListCtrlEdit::OnCombo()
{
	if(!m_pcombo) //If combo box does not exist create one
	{
		m_pcombo = new CComboBox;
		DWORD dwStyle = WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_CLIPSIBLINGS|WS_BORDER|CBS_DROPDOWN|WS_VSCROLL|WS_HSCROLL; 
		CRect rect;
		GetSubItemRect(m_iRow,m_iCol,LVIR_LABEL,rect);
		rect.bottom +=100;
		m_pcombo->Create(dwStyle,rect,this,1002);
		
		m_pcombo->ShowWindow(SW_SHOW);
		m_pcombo->AddString("lab");
		m_pcombo->AddString("mab");
		m_pcombo->AddString("cab and mab and enjoy");
		m_pcombo->AddString("rab");
		m_pcombo->SetHorizontalExtent(800);
		m_pcombo->SendMessage(CB_SETDROPPEDWIDTH,600,0);
		m_pcombo->SetCurSel(3);
		m_pcombo->SetFocus();
		if(m_pEdit) m_pEdit->ShowWindow(SW_HIDE);
	}
	else //If combo box exist just move it
	{
		CRect rect;
		GetSubItemRect(m_iRow,m_iCol,LVIR_LABEL,rect);
		//m_pcombo->SetWindowPos(NULL,rect.left,rect.top,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);
		m_pcombo->SetWindowPos(NULL,rect.left,rect.top,rect.Width(),rect.Height()+100,SWP_SHOWWINDOW);
		//m_pcombo->MoveWindow(rect.left,rect.top,rect.Width(),rect.Height()+200,1);
		m_pcombo->SetCurSel(0);
		m_pcombo->SetFocus();
		if(m_pEdit) m_pEdit->ShowWindow(SW_HIDE);
		
	}
	return 21;
}
*/

void CListCtrlEdit::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	if ( m_bEditable )
	{
		NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
		// TODO: Add your control notification handler code here
		//AfxMessageBox("Clicked On header");
		if(m_pEdit && m_pEdit->IsWindowVisible() )
		{
			m_pEdit->ShowWindow(SW_HIDE); 		
		}
		
	/*
		if(m_pcombo && m_pcombo->IsWindowVisible())
		{	
			m_pcombo->ShowWindow(SW_HIDE);		
		}
	*/
	}

	*pResult = 0;
}
void CListCtrlEdit::vAdjustWhenClickedOnPartialSqures(NMHDR* pNMHDR)
{
	//if(AfxGetThreadState()->m_lastSentMsg.message == WM_NOTIFY)
	//	AfxGetThreadState()->m_lastSentMsg.message = WM_NULL;
	TCHAR buf[123]={0x00};
	_stprintf_s(buf,_T("msg = %x"),AfxGetThreadState()->m_lastSentMsg.wParam );
	//AfxMessageBox(buf);

	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
	TCHAR sBuf[123]={0x00};
	_stprintf_s(sBuf,_T("m_iRow = %d,m_iCol = %d"),pNMListView->iItem,pNMListView->iSubItem);
	//sprintf_s(sBuf,"%d",AfxGetThreadState()->m_lastSentMsg.message);
	//AfxMessageBox(sBuf);
	CRect rect;
	GetSubItemRect(pNMListView->iItem,pNMListView->iSubItem,LVIR_LABEL,rect);
	ClientToScreen(rect);
	CPoint pt(rect.right,rect.bottom);
	CRect rc;
	GetWindowRect(rc);

	//ScreenToClient(&rc);
	_stprintf_s(sBuf,_T("SB=%d,SR=%d,\nL=%d ,T=%d,B=%d,R=%d"),rect.bottom,rect.right,rc.left,rc.top,rc.bottom,rc.right);
	//AfxMessageBox(sBuf);
	//if((rc.top<pt.y )&& (pt.y<rc.bottom))
	if(!rc.PtInRect(pt))
	{
		
		//AfxMessageBox("labamba down");
		SendMessage(WM_VSCROLL,SB_LINEDOWN,0);
		//PostMessage(WM_VSCROLL,SB_LINEDOWN,0);
	}
	
	pt.x=rect.left;
	pt.y =rect.top;
	if(!rc.PtInRect(pt))
	{
		//AfxMessageBox("labamba Up");
		SendMessage(WM_VSCROLL,SB_LINEUP,0);
	}	
}
BOOL CListCtrlEdit::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;

	m_iRow = pNMListView->iItem;		// store clicked item
	m_iCol = pNMListView->iSubItem;

	if ( m_bEditable )
	{
		// TODO: Add your control notification handler code here
		//if(AfxGetThreadState()->m_lastSentMsg.message == WM_VSCROLL)
		//	AfxMessageBox("m_iRow click");
		if(pNMListView->iItem == -1 || pNMListView->iSubItem == -1)
		{
			*pResult =0;
		} else {
			vAdjustWhenClickedOnPartialSqures(pNMHDR);
			//OnSetText();     
/*
			m_iRow = pNMListView->iItem;
			m_iCol = pNMListView->iSubItem;
*/
			switch(m_iCol)
			{
		/*
				case 0:
					OnCombo();
				break;
		*/

				case 1:
				case 2:
				case 3:
				case 4:
					OnEdit();
				break;
			}
		}
	}

	*pResult = 0;

	return FALSE;	// allow parent to handle this message as well (ON_NOTIFY_REFLECT_EX !)
}
void CListCtrlEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	
	
	//if(m_pEdit == NULL || m_pcombo == NULL)
	//	return;
	// TODO: Add your message handler code here and/or call default
	

	switch (nSBCode)
    {
        case SB_TOP:        
			break;
        case SB_BOTTOM:
		//AfxMessageBox("SB_BOTTOM");
			break;
		case SB_PAGEUP:   
        case SB_LINEUP:    
		case SB_PAGEDOWN:
        case SB_LINEDOWN:   
				break;
		case SB_THUMBTRACK: 
			break;
		default: break;
    }
	
	if(m_pEdit)//&& m_pEdit->IsWindowVisible() )
	{
		m_pEdit->ShowWindow(SW_HIDE); 		
	}
	
/*
	if(m_pcombo)//&& m_pcombo->IsWindowVisible())
	{	
		m_pcombo->ShowWindow(SW_HIDE);		
	}
*/
	
	CListCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CListCtrlEdit::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	// TODO: Add your message handler code here and/or call default
	
	if(m_pEdit && m_pEdit->IsWindowVisible() )
	{
		m_pEdit->ShowWindow(SW_HIDE); 		
	}
	
/*
	if(m_pcombo && m_pcombo->IsWindowVisible())
	{	
		m_pcombo->ShowWindow(SW_HIDE);		
	}
*/
	 
	CListCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}


BOOL CListCtrlEdit::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
	switch (((NMHDR*)lParam)->code)
    {
        case HDN_BEGINTRACKW:
        case HDN_BEGINTRACKA:
		{
             *pResult = 0;//TRUE;                // disable tracking 
			if(m_pEdit && m_pEdit->IsWindowVisible() )
			{
				m_pEdit->ShowWindow(SW_HIDE); 		
			}

/*
			if(m_pcombo && m_pcombo->IsWindowVisible())
			{	
				m_pcombo->ShowWindow(SW_HIDE);		
			}
*/
                //return TRUE;                    // Processed message
		}
		
    }
	
    return CListCtrl::OnNotify(wParam, lParam, pResult);

	return 0;
}

/*
How to easily navigate and edit a list view control

We have a list view control; the task is to write simple code to help in navigating
through the controls like how one navigates in an excel sheet, also we need edit the individual cells of the list view control again just like how we edit in an excel sheet.

When I started to look for solutions over the net I found out the code to do such a thing 
was quite complicated, though it ultimately achieved what I set out for. I started to write my own code and my main objective was to keep it as simple as possible while achieving the expected results.

How does the control work:
First run the application, a list view control (3 rows by 9 columns)will appear in a dialog 
application. Press tab 3 to 4 times a combo box appears in the first column.Pressing tab again will make the combo box to disappear and an edit box o appear in the second column, and so on. For navigating backwards you need to press shift+ tab. If you click anywhere except in the header and the last column (4th) in the list control a corresponding control will appear. Scrolling the mouse will make all controls disappear, using the scroll bars will also have a similar effect. As soon as the control is removed from a cell its contents are copied into the cell.

I think the very basic necessities of a navigatable-editable list view control are satisfied.

How simple is the code:
Like many times before I will explain what am doing here. After you shoot up a dialog application and put a list view control in it. Derive a class from CListCtrl I even derived classes from CEdit and CComboBox just in case I need more control on the controls however I do not make any use of it.

I define the following global variables 
	CEdit *m_pEdit = NULL;
	CComboBox *m_pcombo = NULL;
	int m_iRow =0;
	int m_iCol =-1;
The OnInitDialog() function contains some standard code to get the List view control up and running

I declare the following public functions in the CListCtrlEdit the class derived from CListCtrl
	LRESULT  OnEdit();
	LRESULT  OnCombo();
	void OnSetText();

Use PreTranslateMessage(...) to accommodate for TAB and SHIFT+TAB keys. After the m_iRow column management is done I issue a vertical scroll message to the list view control.
Remember I do a Send message and not a post message, because I need to wait till the 
scrolling is over. The code then proceeds to do switch on the m_iCol variable.
I have pre-assigned the first column for combo boxes the second and third for edit boxes.
.So here is where I call OnEdit() or the OnCombo().The OnCombo() function checks 
to see if the m_pcombo is NULL . If it is NULL then no combox box is created it proceed to create one whose parent is the Listview control. and places it at the current m_iRow, m_iCol
cordinates. If Edit box is already created it just moves it to its current m_iRow, m_iCol cordinates.
The OnSetText() function just takes the current control's text and writes it on the current cell.
Then I handle the NM_CLICK message handler of the list view control to make a control disappear from its previous position and appear in the clicked position, this is done in OnClick(...).
The LVN_COLUMNCLICK message is handled to make all the controls disappear.
OnNotify(..) function prompts me when ever the user is trying to resize a column of the
List view control, I grab the opportunity and hide all the controls so that the next time 
the can appear with new sizes.

There might be still some bugs please feel free to fix them and notify me afterwards.

*/


int CListCtrlEdit::InsertColumnEX( int nCol, const LVCOLUMN* pColumn, ELISTCTRLEDIT Editable )
{
	while ((UINT) nCol >= m_vEditable.size() )
	{
		m_vEditable.push_back( elcNotEditable );
	}
	m_vEditable[ nCol ] = Editable;

	return InsertColumn( nCol, pColumn );
}

void CListCtrlEdit::EnableEdit( bool bEditable )
{
	m_bEditable = bEditable;
}

// HitTestEx	- Determine the row index and column index for a point
// Returns	- the row index or -1 if point is not over a row
// point	- point to be tested.
// col		- to hold the column index
int CListCtrlEdit::HitTestEx(CPoint &point, int *col)
{
	int iRowRet = -1;

	int colnum = 0;
	ScreenToClient( &point );
	int row = HitTest( point, NULL );
	
	if( col ) *col = 0;

	// Make sure that the ListView is in LVS_REPORT
	if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
		return row;

	// Get the top and bottom row visible
	row = GetTopIndex();
	int bottom = row + GetCountPerPage();
	if( bottom > GetItemCount() )
		bottom = GetItemCount();
	
	// Get the number of columns
	CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
	int nColumnCount = pHeader->GetItemCount();

//	LPINT aColumnOrder = (LPINT) malloc(nColumnCount*sizeof(int));
	LPINT aColumnOrder = new int[ nColumnCount * sizeof( int ) ];
	ASSERTR(aColumnOrder != NULL);

	// Loop through the visible rows
	for( ;row <= bottom;row++)
	{
		// Get bounding rect of item and check whether point falls in it.
		CRect rect;
		GetItemRect( row, &rect, LVIR_BOUNDS );
		if( rect.PtInRect(point) )
		{

/*
			// Now find the column
			for( colnum = 0; colnum < nColumnCount; colnum++ )
			{
				int colwidth = GetColumnWidth(colnum);
				if( point.x >= rect.left 
					&& point.x <= (rect.left + colwidth ) )
				{
					if( col ) *col = colnum;
					return row;
				}
				rect.left += colwidth;
			}
*/
			// Now find the column
			GetColumnOrderArray(aColumnOrder, nColumnCount);
			for( colnum = 0; colnum < nColumnCount; colnum++ )
			{
				int colwidth = GetColumnWidth(aColumnOrder[ colnum ]);
				if( point.x >= rect.left
					&& point.x <= (rect.left + colwidth ) )
				{
					if( col ) *col = aColumnOrder[ colnum ];
					{
						iRowRet = row;
						row = bottom + 1;	// to leave outer loop
						break;
					}
				}
				rect.left += colwidth;
			}
		}
	}

	delete[] aColumnOrder;

	return iRowRet;
}